
function connectionsInit(){

        ///SVG initialization is in "window.js"
                
        
        //context menu
        window.lineContextMenu = new LineContextMenu();

		//this makes links open in new tab
        externalLinks();

        return;
}

//makes links open new tab 
function externalLinks()
{
 
	if(!document.getElementsByTagName)
		return;
	var anchors = document.getElementsByTagName("a");
	for(var i = 0; i < anchors.length; i++) {
		var anchor = anchors[i];
		if(anchor.getAttribute("href"))
			anchor.target = "_blank";
	}
	
	return;
}

function newLine(self){
	//make line and outline
	self.line = paper.path();
	self.outline = paper.path();
	
	self.outline[0].setAttributeNS(null,'class', 'pointer');
	
	//give outline element reference to element it is listening for
	self.outline.data("listensFor", self.line);
	
	//give both lines a reference to argument tree parent
	self.line.data("parent", self);
	self.outline.data("parent", self);
	
	//event listeners////////////////	
	//on OUTLINE mouseover, make a new line behind LINE to serve to highlight it
		//uses Raphael library methods
	self.outline.mouseover(function () { self.highlightLine() } );
										
	//remove highlight line on mouseout
	self.outline.mouseout(function () { self.unhighlightLine() } );
										
	//context menu
	handlers.invokeLineContextMenu_Line = function () { self.invokeLineContextMenu(event, self.line); };
		self.outline.click(handlers.invokeLineContextMenu_Line);	
	
	return;
}

function newFallacyLabel(self){
	var label = document.createElement("div");
	label.className = "label";
	argumentsContainer.appendChild(label);
	
	label.classList.add("pointer");

	//event listeners///////////////////
	//on label mouseover, highlight line
	label.addEventListener("mouseover", function () { self.highlightLine(); } );
								
	//remove highlight line on mouseout
	label.addEventListener("mouseout", function () { self.unhighlightLine(); } );
								
	//listener for context menu
	handlers.invokeLineContextMenu_Label = function () { self.invokeLineContextMenu(event, self.line); };
		label.addEventListener("click", handlers.invokeLineContextMenu_Label );

	return label;
}

//draw line between self and parent, and, through another function call, between self and all assists
//FIX break this up into more than one function
//"this" is the parent
Node.prototype.drawConnections = function (){
		
		//if an assist node, does not get a line
			//and draw a line to the node to its left
		/*****************
		if (this.displayedDiv.classList.contains("assist") )
		{
			drawAssistConnection(this);
			
		}else{
		*////
			//draw line
			//claims and assists don't need curvy line to parent, so skip drawing that if one of those
			var parent = this.parent;
			if( this !== claim && !this.displayedDiv.classList.contains("assist") ) {
				
				//set coordinates of ends//////
					//self coords (these do get used again in another function)
					this.x1 = this.left + 110; //center of element
					this.y1 = this.top;
					//parent coords
					this.x2 = parent.left + 110; //center of element
					this.y2 = parent.top + parent.displayedDiv.offsetHeight;
				
				//calculate bezier offset (curviness)///////////
					/* a function of horizontal distance from parent
					 * spaces out lines - easier to click
					 * 
					 * logic:
					 * outsideness = distance from center of parent/ maximum distance from center of parent 
					 * bezierOffset = max offset * outsideness
					 */
					var center = parent.left;
					var distanceFromCenter = Math.abs(this.left-center);
					
					//if center child, set manually to avoid dividing by zero
					if (distanceFromCenter === 0){
						
						var bezierOffset = 0; 
	
					}else{ //not directly under parent
	
						//set max distance to index of first (outermost) child
						if (this.indexToParent === 0){
							
							parent.maxDistance = distanceFromCenter; 
						}
						
						var outsideness = distanceFromCenter/parent.maxDistance;
						var bezierOffset = (this.y1-this.y2-5) * outsideness;
					}
				//end bezier offset calculations///////////////
					 			
				//bezier curve control points
				this.xb1 = this.x1;
				this.yb1 = this.y1 - bezierOffset;
				this.xb2 = this.x2;
				this.yb2 = this.yb1;
	
				//actually draw lines//////////	
					//(When styled with CSS anti aliasing seems to be disabled, so styled here)
				
					//visible line////////
						//draw/update
						this.line.attr('path',	'M' + this.x1  + ' ' + this.y1  +
												'C' + this.xb1 + ' ' + this.yb1 +
												' ' + this.xb2 + ' ' + this.yb2 + 
												' ' + this.x2  + ' ' + this.y2);
						//style
						this.line.attr('stroke', 'black');
					
					//invisible border for event listening/////
						//draw/update
						this.outline.attr('path', 'M' + this.x1  + ' ' + this.y1  +
												  'C' + this.xb1 + ' ' + this.yb1 +
												  ' ' + this.xb2 + ' ' + this.yb2 + 
												  ' ' + this.x2  + ' ' + this.y2);
						//style
						this.outline.attr('stroke', 'transparent');
						this.outline.attr('stroke-width', '29');
						this.outline.toFront();
				//end drawing lines///////////////
				
				//draw/update fallacy label, if there is one
				this.changeLabel();
			}//end if not claim

		//******}//end else
		
		//recursively call next child////////
			//start with outer children and work to inner
				//causes inner outlines to be on top of outer outlines - easier to click on
			var leftIndex = 0;
			var rightIndex = this.children.length-1;
			
			var counter = 0 
			var currentIndex;
			while(leftIndex <= rightIndex){
				//alternate outer, inner, outer...
				if((counter%2) === 0){
					currentIndex = leftIndex;
					this.children[currentIndex].drawConnections();
					leftIndex++;
				}else{
					currentIndex = rightIndex;
					this.children[currentIndex].drawConnections();
					rightIndex--;
				}
				

				counter ++;					
			}//end while
		//end recursive calls//////////
		if(this.assists.length)	drawAssistConnections(this);

		return;
}

//draws connection from node to all of its assist nodes with one line, that goes behind them, so looks like
	//line for each one
function drawAssistConnections(assistParent){
	
	//set coordinates
	var ends = {};
	
	var indexLast = assistParent.assists.length - 1;
	
	ends.x1 = assistParent.left + 20;
	ends.y1 = assistParent.top + 25;
	ends.x2 = assistParent.assists[indexLast].left + 20;
	ends.y2 = ends.y1;
		
	//if line does not exist, create it, else, update it
	if (!assistParent.assistConnection || !assistParent.assistConnection.paper)
	{
		assistParent.assistConnection = paper.path(	'M' + ends.x1 + ' ' + ends.y1 +
											'L' + ends.x2 + ' ' + ends.y2);
	}else
	{
		assistParent.assistConnection.attr('path', 	'M' + ends.x1 + ' ' + ends.y1 +
											'L' + ends.x2 + ' ' + ends.y2);
	}
	assistParent.assistConnection.attr('stroke', 'green');
	assistParent.assistConnection.attr('stroke-width', '7');

	//draw connections for children of assists
	for(var i=0,j=assistParent.assists.length; i<j; i++){
		if(assistParent.assists[i]) assistParent.assists[i].drawConnections();
	};
		
}

//FIX complete function
function setEnds(){
	
	
	return ends;
}

Node.prototype.highlightLine = function(){
	
	this.lineHighlight = paper.path('M' + this.x1  + ' ' + this.y1  +
									'C' + this.xb1 + ' ' + this.yb1 +
									' ' + this.xb2 + ' ' + this.yb2 + 
									' ' + this.x2  + ' ' + this.y2);

	this.lineHighlight.attr('stroke', 'yellow');
	this.lineHighlight.attr('stroke-width', '5');
   	this.lineHighlight.toBack();
   	
   	return;
}

Node.prototype.unhighlightLine = function (){
	
	this.lineHighlight.remove();
	
	return;
}

Node.prototype.invokeLineContextMenu = function (lineEvent, line){

	var self = this;
	
	lineEvent.preventDefault();
	
	//if left click
	if(lineEvent.button === 0){
		
		//show context menu at mouse click location
		//left shift needed because arguments container is shifted right whenever a new node exceeds
			//its left most boundary
		lineContextMenu.style.left = (lineEvent.clientX - argumentsContainer.offsetLeft + 17) + "px";
		lineContextMenu.style.top = (lineEvent.clientY - argumentsContainer.offsetTop + 3) + "px";
		lineContextMenu.classList.add("visible");
		
		//so menu has to wait for another click after the calling click before disappearing
		lineEvent.stopPropagation();
		
		//hide menu after clicking again anywhere, then remove event listener
		handlers.bodyClick = function(listEvent) {
													//if click not left mouse button, do nothing
													if(listEvent.button !== 0){
														return;
													}
													
													//if click on a link (whick would be to wikipedia),
														// do nothing because 
														//want to keep menu open for after they come back from
														//wikipedia so they can make their selection
													if(listEvent.target.parentNode.localName === "a"){	
														return;
													}
													
													//if click on list item in menu
													if(listEvent.target.localName === "li"){
														
														self.changeConnection(listEvent.target.innerText);
														self.changeLabel(listEvent.target.innerText)
													}
													
													lineContextMenu.classList.remove("visible");
													document.body.removeEventListener("click", handlers.bodyClick);
												};
		document.body.addEventListener("click", handlers.bodyClick);	
	}
}

Node.prototype.changeConnection = function (label){
		
	//not a fallacy
	if(label === "None"){
		this.line[0].setAttributeNS(null,'class', '');  //line is a Raphael element.  line[0] is the DOM element
													//Raphael has no method to add a class
	}else{//a fallacy
		this.line[0].setAttributeNS(null,'class', 'fallacy');
	}
	
	return;
}


Node.prototype.changeLabel = function (label){
	
	//if label is blank (updating position)
		//if no label
			//do nothing
		//if label
			//update position
			
	//if label is none (deleting label through context menu or closing)
		//if no label
			//do nothing
		//if label
			//remove
			
	//if label is something (adding label or changing label)
		//if no label present
			//make label
		//update label
	
	if (!label){ //when updating position

		//if nothing to update, do nothing
		if(!this.fallacyLabel) {
			
			return;
			
		}else{ //update position
			
			//move the box this much to the left so that the text box is centered
			var xShift = this.fallacyLabel.offsetWidth/2;
			var yShift = this.fallacyLabel.offsetHeight/2;
			
			//get position at 1/3 up from start of line
			var length = this.line.getTotalLength()/4;
			
			//set position
			var coords = this.line.getPointAtLength(length);
			this.fallacyLabel.style.left = (coords.x - xShift) + "px";
			this.fallacyLabel.style.top = (coords.y - yShift) + "px";
			
			return;
		}
	}

	//label set to "none"
	if(label === "None"){  //deleting label
		
		//if no label, do thing
		if(!this.fallacyLabel){

			return;
			
		}else{ //if label exists, remove

			argumentsContainer.removeChild(this.fallacyLabel );
			this.fallacyLabel = null;
			
			return;
		}

		
	}else{//setting fallacy to something or updating position
		
		//no labelDiv exists, make one
		if(!this.fallacyLabel)
			this.fallacyLabel = newFallacyLabel(this);
		
		//set label text
		this.fallacyLabel.innerText = label;
		
		//move the box this much to the left so that the text box is centered
		var xShift = this.fallacyLabel.offsetWidth/2;
		var yShift = this.fallacyLabel.offsetHeight/2;
		
		//get position at 1/3 up from start of line
		var length = this.line.getTotalLength()/4;
		
		//set position
		var coords = this.line.getPointAtLength(length);
		this.fallacyLabel.style.left = (coords.x - xShift) + "px";
		this.fallacyLabel.style.top = (coords.y - yShift) + "px";
		
		return;
	}
}


function LineContextMenu(){
	
	var lineContextMenu = document.createElement('div');
		lineContextMenu.id = 'lineContextMenu';
		lineContextMenu.innerHTML =	"<h3>Logical Fallacy:</h3>" +
									"<ul>" +
										"<li id='fal1'>Ad hominem" +
											"<a href= 'http://en.wikipedia.org/wiki/Ad_hominem'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal2'>Appeal to ignorance" +
											"<a href= 'http://en.wikipedia.org/wiki/Argument_from_ignorance'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal3'>Argument from authority" +
											"<a href= 'http://en.wikipedia.org/wiki/Argument_from_authority'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal4'>Begging the question" +
											"<a href= 'http://en.wikipedia.org/wiki/Begging_the_question'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal5'>False dichotomy" +
											"<a href= 'http://en.wikipedia.org/wiki/False_dilemma'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal6'>Non-sequiter" +
											"<a href= 'http://en.wikipedia.org/wiki/Non_sequitur_(logic)'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal7'>Slippery slope" +
											"<a href= 'http://en.wikipedia.org/wiki/Slippery_slope'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='fal8'>Straw man" +
											"<a href= 'http://en.wikipedia.org/wiki/Straw_man'>" +
												"<div></div>" +
											"</a>" +
										"</li>" +
										"<li id='none'>None</li>"+
									"</ul>";	
		argumentsContainer.appendChild(lineContextMenu);

	return lineContextMenu;
}

